home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
ptv1n2.arc
/
DRAW.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-06-14
|
10KB
|
236 lines
/* draw.c -- Interactive drawing utilities used by the simple
* paint program paint.c
*/
#include <stdio.h>
#include <graphics.h>
#include <alloc.h>
#include <stdlib.h>
#include <time.h>
#include "mouse.h" /* Function prototypes for mouse */
#include "draw.h" /* Function prototypes for draw.c */
/* The fill parameters, drawing colors, and so forth are all kept as global
* variables. From time to time the current drawing, fill, and line
* styles may be changed, so before calling any drawing function make sure
* the various drawing parameters are reset to these global values.
*/
int globalfillstyle; /* The fill style that should be used */
int globalfillcolor; /* Holds the fill color that should be used */
int globaldrawcolor; /* Holds the drawing color to use */
int globallinestyle; /* Holds the line style that should be used */
int wl, wt, wr, wb; /* Window bounds where drawing is to be done */
/* This routine emulates a pencil. While the left mouse button is pressed
* it will draw a trail of connected lines. When the mouse button is
* released, no drawing occurs. To avoid unneccassary drawing, lines are
* only drawn when the mouse's position changes.
*/
void pencil(void)
{
int x, y, oldx, oldy;
setviewport(wl,wt,wr,wb,1); /* Draw in this viewport location */
setcolor(globaldrawcolor); /* Use the global drawing color */
while (1) {
while (!buttonstatus(PRESSED,LEFT_BUTTON)) ; /* Wait until button is */
getmousecoords(&x,&y); /* pressed, Get coordinates. */
if (x < wl || x > wr || y < wt || y > wb) { /* If mouse location outside */
setviewport(0,0,getmaxx(),getmaxy(),1); /* of window */
return; /* restore viewport to full screen */
} /* and exit pencil routine */
oldx = x; oldy = y;
moveto(x-wl,y-wt); /* Set current position to */
/* where drawing begins */
/* As long as the mouse button is */
mousestatus(HIDE_MOUSE); /* Erase the screen where the mouse */
mousestatus(SHOW_MOUSE);
while (!buttonstatus(RELEASED,LEFT_BUTTON)) { /* pressed, get its */
getmousecoords(&x,&y); /* location. If location has */
if (x != oldx || y != oldy) { /* has changed, draw a line */
mousestatus(HIDE_MOUSE); /* to it. Make sure to */
lineto(x-wl,y-wt); /* adjust mouse location */
mousestatus(SHOW_MOUSE); /* to current viewport. */
oldx = x; oldy = y; /* Save mouse location */
}
}
}
}
/* This routine resets a small block of the screen to the background
* color. The erasing is done by drawing a filled bar at the current
* mouse location as long as the left mouse button is pressed.
*/
void erase(void)
{
int x, y, oldx, oldy;
setviewport(wl,wt,wr,wb,1); /* Set the viewport to the drawing */
setcolor(getbkcolor()); /* window. Use the background color */
setfillstyle(SOLID_FILL,getbkcolor()); /* to erase the screen. */
while (1) {
while (!buttonstatus(PRESSED,LEFT_BUTTON));/* Wait for button press */
getmousecoords(&x,&y); /* Get mouse location */
if (x < wl || x > wr || y < wt || y > wb) { /* If mouse outside of */
setviewport(0,0,getmaxx(),getmaxy(),1); /* window, then*/
return; /* restore viewport and return. */
}
oldx = x; oldy = y;
mousestatus(HIDE_MOUSE); /* Erase the screen where the mouse */
bar(x-wl,y-wt,x-wl+ERASERSIZE,y-wt+ERASERSIZE); /* is located */
mousestatus(SHOW_MOUSE);
while (!buttonstatus(RELEASED,LEFT_BUTTON)) { /* Continue to erase */
getmousecoords(&x,&y); /* the screen as long */
if (x != oldx || y != oldy) { /* as the mouse is at */
mousestatus(HIDE_MOUSE); /* a new location and */
bar(x-wl,y-wt,x-wl+ERASERSIZE,y-wt+ERASERSIZE);
mousestatus(SHOW_MOUSE); /* the left button is */
oldx = x; oldy = y; /* pressed */
}
}
}
}
/* The spraycan routine randomly paints pixels in a square region
* whenever the left mouse button is pressed.
*/
void spraycan(void)
{
int i, x, y;
randomize(); /* Begin random function used to */
/* decide where to paint pixels */
setviewport(wl,wt,wr,wb,1); /* Set window to drawing window */
while (1) { /* Wait until the left */
while (!buttonstatus(PRESSED,LEFT_BUTTON)); /* button is pressed */
getmousecoords(&x,&y); /* If mouse is outside */
if (x < wl || x > wr || y < wt || y > wb) { /* of draw window then */
setviewport(0,0,getmaxx(),getmaxy(),1); /* restore window */
return; /* to full screen and */
} /* quit routine */
while (!buttonstatus(RELEASED,LEFT_BUTTON)) {/* Continue spraying */
getmousecoords(&x, &y); /* while the button is */
mousestatus(HIDE_MOUSE); /* pressed */
for (i=0; i<8; i++)
putpixel(x-random(SPRAYSIZE)+5-wl,
y-random(SPRAYSIZE)+5-wt, globaldrawcolor);
for (i=0; i<8; i++)
putpixel(x-random(SPRAYSIZE-2)+3-wl,
y-random(SPRAYSIZE-2)+3-wt, globaldrawcolor);
mousestatus(SHOW_MOUSE);
}
}
}
/* Draw a line while line left mouse button is pressed. Use
* XOR_PUT to provide rubber-banding line feature. Once a line
* is to be fixed it is redrawn with COPY_PUT so that the color
* for the line will be drawn correctly, since XOR_PUT won't always
* yield the correct colors.
*/
void drawlines(void)
{
int x1, y1, x2, y2, oldx2, oldy2;
setviewport(wl,wt,wr,wb,1); /* Use the drawing window */
setlinestyle(globallinestyle,0,NORM_WIDTH); /* and the global */
setcolor(globaldrawcolor); /* settings */
while (1) {
while (!buttonstatus(PRESSED,LEFT_BUTTON)) ;
getmousecoords(&x1,&y1);
if (x1 < wl || x1 > wr || y1 < wt || y1 > wb) {
setviewport(0,0,getmaxx(),getmaxy(),1);
setwritemode(COPY_PUT);
return;
}
setwritemode(XOR_PUT); /* Use XOR_PUT to rubber-band lines */
moveto(x1-wl,y1-wt);
oldx2 = x1; oldy2 = y1;
while (!buttonstatus(RELEASED,LEFT_BUTTON)) {
getmousecoords(&x2,&y2);
if (x2 != oldx2 || y2 != oldy2) {
mousestatus(HIDE_MOUSE);
line(x1-wl,y1-wt,oldx2-wl,oldy2-wt);
line(x1-wl,y1-wt,x2-wl,y2-wt);
mousestatus(SHOW_MOUSE);
oldx2 = x2; oldy2 = y2;
}
}
setwritemode(COPY_PUT); /* Redraw line when set */
mousestatus(HIDE_MOUSE); /* so color will be */
line(x1-wl,y1-wt,x2-wl,y2-wt); /* correct */
mousestatus(SHOW_MOUSE);
}
}
/* Interactively draw a circle */
void drawcircle(void)
{
int cleft, ctop, cright, cbottom, absradius;
unsigned char far *covered1, *covered2;
int centerx, centery, oldleft, oldtop;
int halfx, newx, newy, oldx;
halfx = (wr + wl) / 2;
covered1 = malloc(imagesize(wl, wt, halfx, wb));
covered2 = malloc(imagesize(halfx+1, wt, wr, wb));
if (covered1 == NULL || covered2 == NULL) {
mallocerror();
}
setcolor(globaldrawcolor);
setviewport(wl, wt, wr, wb, 1);
while (1) {
while (!buttonstatus(PRESSED,LEFT_BUTTON)) ;
getmousecoords(¢erx, ¢ery);
if (centerx < wl || centerx > wr || centery < wt || centery > wb) {
setviewport(0, 0, getmaxx(), getmaxy(),1);
free(covered2);
free(covered1);
return;
}
oldleft = centerx; oldtop = centery; oldx = centerx;
mousestatus(HIDE_MOUSE);
getimage(oldleft-wl, oldtop-wt, oldleft-wl, oldtop-wt, covered1);
getimage(oldleft+1-wl, oldtop-wt, oldleft+1-wl, oldtop-wt, covered2);
mousestatus(SHOW_MOUSE);
while (!buttonstatus(RELEASED,LEFT_BUTTON)) {
getmousecoords(&newx, &newy);
absradius = abs(centerx - newx);
/* Clip the region that must be saved below the circle
* to the boundaries of the drawing window
*/
if (centerx-absradius < wl) cleft = wl;
else cleft = centerx - absradius;
if (centerx+absradius > wr) cright = wr;
else cright = centerx + absradius;
if (centery-absradius < wt) ctop = wt;
else ctop = centery - absradius;
if (centery+absradius > wb) cbottom = wb;
else cbottom = centery + absradius;
/* If the size of the circle has changed, redraw it */
if (newx != oldx) {
mousestatus(HIDE_MOUSE);
putimage(oldleft-wl, oldtop-wt, covered1, COPY_PUT);
putimage(centerx+1-wl, oldtop-wt, covered2, COPY_PUT);
getimage(cleft-wl, ctop-wt, centerx-wl, cbottom-wt, covered1);
getimage(centerx+1-wl, ctop-wt, cright-wl, cbottom-wt, covered2);
if (absradius != 0)
circle(centerx-wl, centery-wt, absradius);
mousestatus(SHOW_MOUSE);
oldleft = cleft; oldtop = ctop; oldx = newx;
}
}
}
}
/* This function is called if a malloc() fails. Place your
* own error handler here.
*/
void mallocerror(void)
{
closegraph();
printf("Not enough memory");
exit(1);
}